import base64

from django.shortcuts import render
import pickle
# Create your views here.
# from django.utils.baseconv import base64
from django_redis import get_redis_connection
from rest_framework import status
from rest_framework.response import Response
from rest_framework.views import APIView

from goods.models import SKU
from .serializers import UserCartSerializers, CartSerializer, UserPutSerializer, UserDeleteSerializer


class UserCart(APIView):
    # 重新写一个方法可以让APIView不去校验token
    def perform_authentication(self,request):
        pass

    def post(self,request):

        serializer=UserCartSerializers(data=request.data)
        serializer.is_valid(raise_exception=True)
        sku_id=serializer.validated_data['sku_id']
        count=serializer.validated_data['count']
        selected=serializer.validated_data['selected']
        # 判断用户是否存在
        try:
            user=request.user
        except Exception as e:
            user=None
        if user is None :
            # 用户不存在，数据存在cookie
            # 现查你以前有没有存入这个值，如果有那就添加
            # 尝试从cookie中取
            cookie = request.COOKIES.get('cart')
            # 如果cookie存在
            if cookie:
                # 返回的是一串字符串
                cookie=cookie.encode()
                # 返回的是b'asdfghjkl
                cookie=base64.b64decode(cookie)
                # 此时返回的是b'/xx0/xx1/xx2
                ret_dict=pickle.loads(cookie)
            # 如果之前我没设置过cookie
            else:
                ret_dict = {}
            # 这里看你之前有没有添加商品
            if sku_id in ret_dict:
                # 前期添加过,只是增加数量
                oragin_count=ret_dict[sku_id]['count']
                count=oragin_count+count
            # 这里开始设置
            ret_dict[sku_id]={
                'count':count,
                'selected':selected
            }
            ret_dict=pickle.dumps(ret_dict)
            # 此时返回值b'/xx1/xx2/xx3
            ret_dict=base64.b64encode(ret_dict)
            # 此时返回的值b'asdfghjk
            ret_dict=ret_dict.decode()
            # 此时返回值为字符串
            # 在响应里设置cookie
            response = Response(serializer.data,status=status.HTTP_201_CREATED)
            response.set_cookie('cart',ret_dict)
            return response
        else:
            if user.is_authenticated:
                # 说明用户有过登陆
                user_id=user.id
                # 用户存在数据存在redis
                redis_connect=get_redis_connection('cart')
                '''hincrby(name, key, amount=1)'''
                redis_connect.hincrby('cart_%s' % user_id,sku_id,amount=count)
                if selected:
                    # 这里我要存的值为set
                    # sadd(name,key)
                    redis_connect.sadd('cart_selected_%s' % user_id,sku_id)
                return Response(serializer.data,status=status.HTTP_201_CREATED)

    def get(self,request):
        # 判断用户是否存在
        try:
            user = request.user
        except Exception as e:
            user = None
        if user is not None and user.is_authenticated:
            # 说明用户以登录
            redis_connect = get_redis_connection('cart')
            user_id=user.id
            redis_dict=redis_connect.hgetall('cart_%s' % user_id)
            # print(redis_dict)
            '''返回值为｛sku_id:count｝  {b'1':b'1'}'''
            ret_dict={}
            redis_selected_dict = redis_connect.smembers('cart_selected_%s' % user_id)
            # 返回值｛sku_id｝
            for sku_id,count in redis_dict.items():
                # print(sku_id,count)
                '''要转换成的样子sku_id:{'count':xxxx,'selected':yyyy}'''
                ret_dict[int(sku_id)]={
                    'count':int(count),
                    'selected':sku_id in redis_selected_dict
                }
            '''smembers(name)'''
        else:
            # 在cookie中查询
            # 尝试从cookie中取
            cookie = request.COOKIES.get('cart')
            # 如果cookie存在
            if cookie:
                # 返回的是一串字符串
                cookie = cookie.encode()
                # 返回的是b'asdfghjkl
                cookie = base64.b64decode(cookie)
                # 此时返回的是b'/xx0/xx1/xx2
                ret_dict = pickle.loads(cookie)
            else:
                ret_dict={}
        key_dict=ret_dict.keys()
        # 返回｛sku_id｝
        sku_goods=SKU.objects.filter(id__in=key_dict)
        '''这里返回的是商品的查询集，查出来的没有count和selected因此要手动往查询集添加count和selected'''
        for sku in sku_goods:
            sku.count=ret_dict[sku.id]['count']
            sku.selected=ret_dict[sku.id]['selected']
        # 加入count
        serializer=CartSerializer(sku_goods,many=True)
        response=Response(serializer.data)
        return response

    def put(self,request):
        serializer = UserPutSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        sku_id = serializer.validated_data['sku_id']
        count = serializer.validated_data['count']
        selected = serializer.validated_data['selected']
        # 判断用户是否存在
        try:
            user = request.user
        except Exception as e:
            user = None
        if user is not None and user.is_authenticated:
            # 说明用户已经登录
            # 操作redis
            user_id=user.id
            redis_connect = get_redis_connection('cart')
            '''hset(name, key, value)'''
            '''redis_connect.hincrby('cart_%s' % user_id,sku_id,amount=count)'''
            redis_connect.hset('cart_%s' % user_id,sku_id,count)
            if selected:
                redis_connect.sadd('cart_selected_%s' % user_id, sku_id)
            else:
                '''srem(name, *values)'''
                redis_connect.srem('cart_selected_%s' % user_id, sku_id)
            return Response(serializer.data)
        else:
            # 说明没有登录
            # 尝试从cookie中取
            cookie = request.COOKIES.get('cart')
            # 如果cookie存在
            if cookie:
                # 返回的是一串字符串
                cookie = cookie.encode()
                # 返回的是b'asdfghjkl
                cookie = base64.b64decode(cookie)
                # 此时返回的是b'/xx0/xx1/xx2
                ret_dict = pickle.loads(cookie)
            # 如果之前我没设置过cookie
            else:
                ret_dict = {}
            # 这里开始设置
            ret_dict[sku_id] = {
                'count': count,
                'selected': selected
            }
            ret_dict = pickle.dumps(ret_dict)
            # 此时返回值b'/xx1/xx2/xx3
            ret_dict = base64.b64encode(ret_dict)
            # 此时返回的值b'asdfghjk
            ret_dict = ret_dict.decode()
            # 此时返回值为字符串
            # 在响应里设置cookie
            response = Response(serializer.data, status=status.HTTP_201_CREATED)
            response.set_cookie('cart', ret_dict)
            return response

    def delete(self,request):
        serializer = UserDeleteSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        sku_id = serializer.validated_data['sku_id']
        # 判断用户是否存在
        try:
            user = request.user
        except Exception as e:
            user = None
        if user is not None and user.is_authenticated:
            # 说明用户已经登录
            # 操作redis
            user_id=user.id
            redis_connect = get_redis_connection('cart')
            '''hdel(name, *keys)'''
            redis_connect.hdel('cart_%s' % user_id,sku_id)
            return Response(status=status.HTTP_204_NO_CONTENT)
        else:
            # 尝试从cookie中取
            cookie = request.COOKIES.get('cart')
            # 如果cookie存在
            if cookie:
                # 返回的是一串字符串
                cookie = cookie.encode()
                # 返回的是b'asdfghjkl
                cookie = base64.b64decode(cookie)
                # 此时返回的是b'/xx0/xx1/xx2
                ret_dict = pickle.loads(cookie)
                # ret_dict.delete(ret_dict[sku_id])
                del ret_dict[sku_id]
                ret_dict = pickle.dumps(ret_dict)
                # 此时返回值b'/xx1/xx2/xx3
                ret_dict = base64.b64encode(ret_dict)
                # 此时返回的值b'asdfghjk
                ret_dict = ret_dict.decode()
                response = Response(status=status.HTTP_204_NO_CONTENT)
                response.set_cookie('cart', ret_dict)
                return response
